package com.aegis.manage.service.auth.app;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.aegis.common.enums.PermissionTypeEnum;
import com.aegis.common.mybatis.model.PageResult;
import com.aegis.common.utils.AssertUtil;
import com.aegis.core.enums.AegisHttpMethod;
import com.aegis.manage.api.request.*;
import com.aegis.manage.api.vo.ApiInfoVO;
import com.aegis.manage.api.vo.ApiPermissionVO;
import com.aegis.manage.api.vo.AuthPermissionTypeVO;
import com.aegis.manage.api.vo.PermissionGroupVO;
import com.aegis.manage.mapper.*;
import com.aegis.manage.model.dos.AuthApiPermission;
import com.aegis.manage.model.dos.AuthApiPermissionGroup;
import com.aegis.manage.model.dos.AuthAppPermissionGroupMapping;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author wuweixin
 *
 * @Version 1.0
 * @Descritube
 */
@Service
@Slf4j
public class AuthAppPermissionServiceImpl implements AuthAppPermissionService {

    @Autowired
    private SysPermissionMapper sysPermissionMapper;

    @Autowired
    private AuthApiPermissionMapper authApiPermissionMapper;

    @Autowired
    private AuthApiPermissionGroupMapper authApiPermissionGroupMapper;

    @Autowired
    private AuthAppPermissionAssignmentMapper authAppPermissionAssignmentMapper;

    @Autowired
    private AuthAppPermissionGroupMappingMapper authAppPermissionGroupMappingMapper;

    @Override
    public PageResult<ApiInfoVO> queryApiPage(QueryApiPageRequest request) {
        IPage<ApiInfoVO> apiInfoVOIPage = sysPermissionMapper
                .queryApiInfoPage(new Page<>(request.getCurrent(), request.getSize()),
                        request.getExcludeGroupId(),
                        request.getKeywords());
        return PageResult.exchange(apiInfoVOIPage);
    }

    @Override
    public void insertApi(AddApiRequest request) {
        AegisHttpMethod.toEnum(request.getMethod());
        Long l = authApiPermissionMapper.selectCount(new LambdaQueryWrapper<AuthApiPermission>()
                .eq(AuthApiPermission::getApi, request.getApi())
                .eq(AuthApiPermission::getMethod, request.getMethod()));
        AssertUtil.operateFailed(l > 0, "已存在的接口地址");
        AuthApiPermission authApiPermission = new AuthApiPermission();
        authApiPermission.setApi(request.getApi());
        authApiPermission.setName(request.getName());
        authApiPermission.setRemark(request.getRemark());
        authApiPermission.setMethod(request.getMethod());
        authApiPermissionMapper.insert(authApiPermission);
    }

    @Override
    public void updateApi(UpdateApiRequest request) {
        AuthApiPermission authApiPermission = authApiPermissionMapper.selectById(request.getId());
        AssertUtil.operateFailed(authApiPermission == null, "接口不存在");
        BeanUtils.copyProperties(request, authApiPermission);
        List<AuthApiPermission> authApiPermissions = authApiPermissionMapper.selectList(new LambdaQueryWrapper<AuthApiPermission>()
                .eq(AuthApiPermission::getApi, authApiPermission.getApi())
                .eq(AuthApiPermission::getMethod, authApiPermission.getMethod()));
        if (CollectionUtil.isNotEmpty(authApiPermissions)) {
            AssertUtil.operateFailed(authApiPermissions.size() > 1, "存在同样的接口");
            for (AuthApiPermission apiPermission : authApiPermissions) {
                AssertUtil.operateFailed(!apiPermission.getId().equals(request.getId()), "存在同样的接口");
            }
        }
        authApiPermissionMapper.updateById(authApiPermission);
    }

    @Override
    public void delApi(String id) {
        AuthApiPermission authApiPermission = authApiPermissionMapper.selectById(id);
        AssertUtil.operateFailed(authApiPermission == null, "删除失败");
        AssertUtil.operateFailed(authApiPermission.getSource() == 1, "系统内置接口不能删除");
        AssertUtil.operateFailed(authApiPermissionMapper.deleteById(id) <= 0, "删除失败");
    }

    @Override
    public PageResult<PermissionGroupVO> queryPermissionGroupPage(QueryPermissionGroupPageRequest request) {
        IPage<PermissionGroupVO> permissionGroupPage = sysPermissionMapper
                .queryPermissionGroupPage(new Page<>(request.getCurrent(), request.getSize()), request.getExcludeAppId(), request.getKeywords());
        return PageResult.exchange(permissionGroupPage);
    }

    @Override
    public void insertPermissionGroup(AddPermissionGroupRequest request) {
        Long l = authApiPermissionGroupMapper.selectCount(new LambdaQueryWrapper<AuthApiPermissionGroup>()
                .eq(AuthApiPermissionGroup::getName, request.getName())
                .or()
                .eq(AuthApiPermissionGroup::getGroupKey, request.getGroupKey()));
        AssertUtil.operateFailed(l > 0, "已存在的权限组");
        AuthApiPermissionGroup authApiPermissionGroup = new AuthApiPermissionGroup();
        authApiPermissionGroup.setName(request.getName());
        authApiPermissionGroup.setGroupKey(request.getGroupKey());
        authApiPermissionGroup.setRemark(request.getRemark());
        authApiPermissionGroupMapper.insert(authApiPermissionGroup);
    }

    @Override
    public void updatePermissionGroup(UpdatePermissionGroupRequest request) {
        AuthApiPermissionGroup authApiPermissionGroup = authApiPermissionGroupMapper.selectById(request.getId());
        AssertUtil.operateFailed(authApiPermissionGroup == null, "权限组不存在");
        Long count = authApiPermissionGroupMapper.selectCount(new LambdaQueryWrapper<AuthApiPermissionGroup>()
                .eq(AuthApiPermissionGroup::getName, request.getName())
                .or()
                .eq(AuthApiPermissionGroup::getGroupKey, request.getGroupKey())
                .ne(AuthApiPermissionGroup::getId, request.getId()));
        AssertUtil.operateFailed(count > 0, "已存在的权限组");

        BeanUtils.copyProperties(request, authApiPermissionGroup);
        authApiPermissionGroupMapper.updateById(authApiPermissionGroup);
    }

    @Override
    public void delPermissionGroup(String id) {
        AuthApiPermissionGroup authApiPermissionGroup = authApiPermissionGroupMapper.selectById(id);
        AssertUtil.operateFailed(authApiPermissionGroup == null, "权限组不存在");
        AssertUtil.operateFailed(authApiPermissionGroupMapper.deleteById(id) <= 0, "删除失败");

    }

    @Override
    public PageResult<ApiPermissionVO> queryGroupApiPermissionPage(QueryGroupApiPermissionPageRequest request) {
        IPage<ApiPermissionVO> apiPermissionVOIPage = sysPermissionMapper.queryGroupApiPermissionPage(new Page<>(request.getCurrent(),
                        request.getSize()),
                request.getGroupId(),
                request.getKeywords());
        for (ApiPermissionVO record : apiPermissionVOIPage.getRecords()) {
            PermissionTypeEnum anEnum = PermissionTypeEnum.getEnum(record.getType());
            if (anEnum == null) {
                continue;
            }
            record.setTypeName(anEnum.getName());
        }
        return PageResult.exchange(apiPermissionVOIPage);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void bindApiPermission(BindApiPermissionRequest request) {
        Long l = authApiPermissionMapper.selectCount(new LambdaQueryWrapper<AuthApiPermission>().in(AuthApiPermission::getId, request.getApiId().stream()
                .map(permissionTypeRequest -> permissionTypeRequest.getApiId()).collect(Collectors.toList())));
        AssertUtil.operateFailed(l <= 0 || request.getApiId().size() != l, "部分api不存在");
        AssertUtil.operateFailed(authApiPermissionGroupMapper.selectById(request.getGroupId()) == null, "权限组不存在");
        AssertUtil.operateFailed(authAppPermissionGroupMappingMapper.selectCount(new LambdaQueryWrapper<AuthAppPermissionGroupMapping>()
                .eq(AuthAppPermissionGroupMapping::getPermissionGroupId, request.getGroupId())
                .in(AuthAppPermissionGroupMapping::getPermissionId, request.getApiId().stream().map(permissionTypeRequest
                        -> permissionTypeRequest.getApiId()).collect(Collectors.toList()))) > 0, "存在已绑定的接口");
        for (PermissionTypeRequest permissionTypeRequest : request.getApiId()) {
            PermissionTypeEnum type = PermissionTypeEnum.getEnum(permissionTypeRequest.getType());
            AssertUtil.operateFailed(type == null, "类型错误");
            AuthAppPermissionGroupMapping authAppPermissionGroupMapping = new AuthAppPermissionGroupMapping();
            authAppPermissionGroupMapping.setPermissionId(permissionTypeRequest.getApiId());
            authAppPermissionGroupMapping.setPermissionGroupId(request.getGroupId());
            authAppPermissionGroupMapping.setType(permissionTypeRequest.getType());
            authAppPermissionGroupMappingMapper.insert(authAppPermissionGroupMapping);
        }
    }

    @Override
    public List<AuthPermissionTypeVO> queryPermissionType() {
        List<AuthPermissionTypeVO> result = new ArrayList<>();
        for (PermissionTypeEnum value : PermissionTypeEnum.values()) {
            result.add(new AuthPermissionTypeVO(value.getName(), value.getType()));
        }
        return result;
    }

    @Override
    public void delGroupApi(String id) {
        AssertUtil.operateFailed(authAppPermissionGroupMappingMapper.deleteById(id) <= 0, "删除失败");
    }

}
